library(tidyverse)
library(ggpubr)
library(scales)
library(glue)
library(plotly)
library(lubridate)
library(ggplot2)
library(rAmCharts)
library(scales)
library(dplyr)Pada LBB (Learning by Building) ini akan dilakukan Data Visualization menggunakan dataset IMDb. IMDb (Internet Movie Database) adalah sebuah basis data daring informasi yang berkaitan dengan film, acara televisi, video rumahan, dan permainan video, dan acara internet, termasuk daftar pemeran, biografi kru produksi dan personil, ringkasan alur cerita, trivia, dan ulasan serta penilaian oleh penggemar. Sebuah fitur penggemar tambahan, papan pesan, telah dinonaktifkan pada Februari 2017. Awalnya situs ini dioperasikan oleh penggemar, lalu basis data kemudian dimiliki dan dioperasikan oleh IMDB.com Inc., sebuah anak perusahaan dari Amazon.
Hal paling pertama yang harus dilakukan adalah pastikan lokasi folder dataset yang ingin diinput sama dengan Rmd ini. Kemudian, lanjut dengan read dataset. File dataset yang digunakan yaitu imdb.csv.
imdb <- read.csv("imdb.csv", stringsAsFactors = T)Dataset telah terbaca dan terinput dengan nama imdb. Untuk mengetahui isi dataset tersebut, lakukan ke tahap selanjutnya yaitu dengan cara menginspeksi data.
head(imdb)dim (imdb)#> [1] 6178 14
Terlihat bahwa data terdiri dari 6178 baris dan 14 kolom. Kemudian, cek missing value apakah ada atau tidak
anyNA(imdb)#> [1] FALSE
colSums(is.na(imdb))#> Name Date Rate Votes Genre Duration
#> 0 0 0 0 0 0
#> Type Certificate Episodes Nudity Violence Profanity
#> 0 0 0 0 0 0
#> Alcohol Frightening
#> 0 0
Terlihat bahwa tidak ada missing value, sehingga data siap diolah ke tahap selanjutnya.
summary(imdb)#> Name Date Rate Votes
#> King Kong : 5 Min. :1922 7.3 : 273 No Votes: 185
#> Cat People : 4 1st Qu.:1998 7.2 : 235 132 : 5
#> Flatliners : 4 Median :2011 7.1 : 227 2,458 : 4
#> Get Shorty : 4 Mean :2006 7.6 : 226 20,377 : 4
#> Little Women : 4 3rd Qu.:2019 6.8 : 225 21,413 : 4
#> Lost in Space: 4 Max. :2023 6.6 : 224 25,963 : 4
#> (Other) :6153 (Other):4768 (Other) :5972
#> Genre Duration Type Certificate
#> Comedy : 268 60 : 352 Film :4446 R :1885
#> Drama : 259 None : 301 Series:1732 PG-13 :1147
#> Crime, Drama, Mystery: 220 30 : 246 TV-MA : 641
#> Comedy, Drama : 199 97 : 122 TV-14 : 575
#> Drama, Romance : 189 100 : 117 PG : 530
#> Action, Crime, Drama : 171 90 : 117 None : 450
#> (Other) :4872 (Other):4923 (Other): 950
#> Episodes Nudity Violence Profanity Alcohol
#> - :4446 Mild :2292 Mild :1703 Mild :2077 Mild :3257
#> 10 : 82 Moderate:1251 Moderate:1814 Moderate:1646 Moderate:1051
#> 20 : 65 No Rate : 707 No Rate : 759 No Rate : 745 No Rate : 812
#> 16 : 53 None :1459 None : 674 None : 658 None : 771
#> 12 : 49 Severe : 469 Severe :1228 Severe :1052 Severe : 287
#> 8 : 46
#> (Other):1437
#> Frightening
#> Mild :1587
#> Moderate:1969
#> No Rate : 858
#> None : 858
#> Severe : 906
#>
#>
Dari summary tersebut, dapat diperoleh beberapa informasi:
Setelah mengetahui beberapa informasi yang diperoleh dari summary tersebut, diperoleh ide visualization apa yang akan dibuat. Sebelum membuat visualization, diperlukan pengolahan data agar proses pembuatan visualization bekerja dengan baik dan benar. Pertama, cek tipe data dari setiap kolom dataset imdb
str(imdb)#> 'data.frame': 6178 obs. of 14 variables:
#> $ Name : Factor w/ 4820 levels "'Allo 'Allo!",..: 2569 3861 4042 4589 1113 3497 1362 1736 4679 3148 ...
#> $ Date : int 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 ...
#> $ Rate : Factor w/ 77 levels "1.2","1.9","2.0",..: 55 42 43 43 62 67 52 77 55 62 ...
#> $ Votes : Factor w/ 4802 levels "1,000","1,015",..: 308 3927 2187 2444 4486 480 1024 4802 3495 1800 ...
#> $ Genre : Factor w/ 377 levels "Action","Action, Adventure",..: 14 236 225 13 6 177 4 6 113 167 ...
#> $ Duration : Factor w/ 203 levels "100 ","101 ",..: 70 192 23 200 61 126 17 203 203 143 ...
#> $ Type : Factor w/ 2 levels "Film","Series": 1 1 1 1 1 2 1 2 2 2 ...
#> $ Certificate: Factor w/ 23 levels "(Banned)","Approved",..: 13 14 14 13 13 17 13 9 15 17 ...
#> $ Episodes : Factor w/ 284 levels "-","10","100",..: 1 1 1 1 1 131 1 2 92 145 ...
#> $ Nudity : Factor w/ 5 levels "Mild","Moderate",..: 1 4 2 4 4 1 1 3 4 5 ...
#> $ Violence : Factor w/ 5 levels "Mild","Moderate",..: 2 4 5 2 2 4 2 3 2 1 ...
#> $ Profanity : Factor w/ 5 levels "Mild","Moderate",..: 1 5 5 2 4 5 2 3 1 5 ...
#> $ Alcohol : Factor w/ 5 levels "Mild","Moderate",..: 1 4 2 1 1 1 4 3 1 2 ...
#> $ Frightening: Factor w/ 5 levels "Mild","Moderate",..: 2 2 2 2 2 4 1 3 2 1 ...
Ternyata diperlukan deselect beberapa kolom karena tidak diperlukan, menghapus koma pada isi kolom Votes dan mengubah tipe data beberapa kolom. Proses tersebut disebut cleansing data, hasil pengolahan data disimpan dengan nama imdb_clean.
# Cleansing Data
imdb_clean <- imdb %>%
select(-c(Duration,Certificate,Episodes)) %>% # deselect beberapa kolom
mutate(
Name = as.character(Name),# mengubah tipe data
Rate = as.numeric(as.character(Rate)),
Votes = as.numeric(gsub(",","",Votes)),
Genre = as.character(Genre),
Nudity = as.character(Nudity),
Violence = as.character(Violence),
Profanity = as.character(Profanity),
Alcohol = as.character(Alcohol),
Frightening = as.character(Frightening),
Type = as.character(Type)
)Ternyata menghasilkan Warning yaitu adanya NA. Untuk lebih akuratnya, cek NA pada dataset imdb_clean tersebut
anyNA(imdb_clean)#> [1] TRUE
colSums(is.na(imdb_clean))#> Name Date Rate Votes Genre Type
#> 0 0 185 185 0 0
#> Nudity Violence Profanity Alcohol Frightening
#> 0 0 0 0 0
Ternyata benar, terdapat nilai NA di kolom Rate dan Votes. Untuk mengatasinya, ubah nilai NA menjadi 0
imdb_clean[is.na(imdb_clean)] = 0Cek kembali apakah masih terdapat NA
anyNA(imdb_clean)#> [1] FALSE
Terlihat bahwa tidak ada NA lagi, sehingga data siap diolah ke tahap selanjutnya yaitu data wrangling
# Data Wrangling
# Case 1
imdb_count_type <- imdb_clean %>%
group_by(Type) %>%
summarise(count=n()) %>%
ungroup() %>%
arrange(-count)
# Case 2
imdb_10films <- imdb_clean %>%
filter(Type==imdb_count_type$Type[1]) %>% # filter untuk film
group_by(Name) %>%
summarise(mean_rate=mean(Rate)) %>%
ungroup() %>%
arrange(-mean_rate) %>%
top_n(10)
# Case 3
imdb_10series <- imdb_clean %>%
filter(Type==imdb_count_type$Type[2]) %>% # filter untuk series
group_by(Name) %>%
summarise(mean_rate=mean(Rate)) %>%
ungroup() %>%
arrange(-mean_rate) %>%
top_n(10)
# Case 4
imdb_year <- imdb_clean %>%
group_by(Date) %>%
summarise(count=n()) %>%
ungroup() %>%
arrange(-count)
# Case 5
imdb_count_nudity <- imdb_clean %>%
group_by(Nudity) %>%
summarise(count=n()) %>%
ungroup() %>%
arrange(-count)PLOT 1
Visualisasi persentasi banyaknya data film dan series:
plot1 <- amPie(data.frame(label = as.factor(names(table(imdb_clean$Type))), value = as.vector(table(imdb_clean$Type))), main = "Percentage Data of Films and Series",mainColor="black",theme="light")
plot1Dari visualisasi di atas diperoleh bahwa persentase data film itu lebih banyak yaitu 71.97% atau 4446 data, dan persentase data series 28.03% atau 1732 data.
PLOT 2
Visualisasi judul film berdasarkan rating teratas:
imdb_films <- imdb_10films %>%
mutate(label=glue("Name: {Name}
Average Views: {comma(mean_rate)}"))
plot2 <- ggplot(imdb_films, aes(x = reorder(Name, mean_rate),
y = mean_rate,
text = label)) +
geom_segment(aes(x=reorder(Name, mean_rate), xend=reorder(Name, mean_rate), y=0,yend=mean_rate), color="red") +
geom_point(color="black") +
coord_flip() +
labs(title = "TOP FILMS RATING",
x = NULL,
y = "Average Rate") +
scale_y_continuous(labels = comma) +
theme_minimal()
ggplotly(plot2, tooltip = "text")Dari visualisasi di atas diperoleh bahwa judul film yang menduduki rating teratas yaitu Toma dan The Shawshank Redemption mempunyai rating yang sama yaitu 9.3 kemudian disusul oleh film The Godfather dengan rating 9.2, dsb
PLOT 3
Visualisasi judul series berdasarkan rating teratas:
imdb_series <- imdb_10series %>%
mutate(label=glue("Name: {Name}
Average Views: {comma(mean_rate)}"))
plot3 <- ggplot(imdb_series, aes(x = reorder(Name, mean_rate),
y = mean_rate,
text = label)) +
geom_segment(aes(x=reorder(Name, mean_rate), xend=reorder(Name, mean_rate), y=0,yend=mean_rate), color="red") +
geom_point(color="black") +
coord_flip() +
labs(title = "TOP 10 SERIES RATING",
x = NULL,
y = "Average Rate") +
scale_y_continuous(labels = comma) +
theme_minimal()
ggplotly(plot3, tooltip = "text")Dari visualisasi di atas diperoleh bahwa judul series yang menduduki rating teratas yaitu Aspirants dengan rating 9.7 kemudian disusul oleh The Chosen dan Bluey yang mempunyai rating yang sama yaitu 9.6, dsb
PLOT 4
Visualisasi judul film/series berdasarkan tahun:
imdb_count <- imdb_year %>%
mutate(label = glue(
"Year: {Date}
Count: {count}"
))
plot4 <- ggplot(imdb_count, aes(x=Date, y= count))+
geom_line(col="red") +
geom_point(aes(text=label), col="black") +
labs(
title = glue("Years of Film/Series Production"),
x = "Years",
y = "Count"
) +
theme_minimal()
ggplotly(plot4, tooltip = "text")Dari visualisasi di atas diperoleh bahwa tahun produksi yang menghasilkan film/series paling banyak yaitu 2021 yaitu sebanyak 736 data dan yang paling sedikit yaitu tahun 1922 yaitu 1 data.
PLOT 5
Dari unsur yang terdapat pada setiap film/series, disini hanya akan dibuat plot berdasarkan unsur Nudity Level saja
imdb_count2 <- imdb_count_nudity %>%
mutate(label = glue(
"Nudity: {Nudity}
Count: {count}"
))
plot5 <- ggplot(data = imdb_count2, aes(x = count,
y = reorder(Nudity, count), # reorder(A, berdasarkan B)
text = label)) +
geom_col(aes(fill = count)) +
labs(title = "NUDITY LEVEL",
x = "Count",
y = NULL) +
theme_minimal() +
theme(legend.position = "none")
ggplotly(plot5, tooltip = "text")Dari visualisasi di atas diperoleh bahwa Nudity Level yang paling tinggi adalah level Mild dan yang paling rendah adalah level Severe.